package es.tikitaka.actions.colegiados;

import java.util.Date;
import java.util.List;

import org.jboss.seam.ScopeType;
import org.jboss.seam.annotations.Begin;
import org.jboss.seam.annotations.End;
import org.jboss.seam.annotations.FlushModeType;
import org.jboss.seam.annotations.In;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;
import org.jboss.seam.faces.FacesMessages;
import org.richfaces.event.UploadEvent;
import org.richfaces.model.UploadItem;

import es.tikitaka.dao.ColegiadoService;
import es.tikitaka.dao.ColegiosDicService;
import es.tikitaka.dao.DireccionService;
import es.tikitaka.dao.MunicipioDicService;
import es.tikitaka.dao.PartColegiadoService;
import es.tikitaka.dao.ProvinciaDicService;
import es.tikitaka.dictionary.ColegioDic;
import es.tikitaka.dictionary.MunicipioDic;
import es.tikitaka.dictionary.ProvinciaDic;
import es.tikitaka.domain.Direccion;
import es.tikitaka.domain.Temporada;
import es.tikitaka.domain.colegiado.Colegiado;
import es.tikitaka.domain.colegiado.PartColegiado;

/**
 * 
 * @author Saúl Domínguez
 * @since 2010
 * @category PFC
 */

@Name("colegiadoAction")
@Scope(ScopeType.CONVERSATION)
public class ColegiadoAction {

	private int modo;
	private boolean nuevo;

	private Colegiado colegiado;
	private String dni;
	private PartColegiado participacion;

	private Colegiado newColegiado;
	private Integer edad;
	private boolean guardado;

	private byte[] fotoC;

	private List<ProvinciaDic> listaProvincias;
	private List<ProvinciaDic> listaProvinciasDir;
	private List<MunicipioDic> listaMunicipios;
	private List<MunicipioDic> listaMunicipiosDir;

	private List<ColegioDic> listaColegios;
	private List<PartColegiado> listaParticipaciones;

	@In(create = true)
	private ProvinciaDicService provinciaService;

	@In(create = true)
	private MunicipioDicService municipioService;

	@In(create = true)
	private ColegiosDicService colegioService;

	@In(create = true)
	private ColegiadoService colegiadoService;

	@In(create = true)
	private DireccionService direccionService;

	@In(create = true)
	private ColegiadoSearch colegiadoSearch;

	@In(create = true)
	private PartColegiadoService partColegiadoService;

	/**
	 * Constructor por defecto
	 */
	public ColegiadoAction() {
		// TODO Auto-generated constructor stub
	}

	/**
	 * Método para la creación de un nuevo colegiado
	 */
	public void nuevoColegiado() {

		newColegiado = new Colegiado();
		listaProvincias = provinciaService.getList();
		listaProvinciasDir = provinciaService.getList();
		listaColegios = colegioService.getList();
		Direccion dir = new Direccion();
		newColegiado.setDireccion(dir);
		nuevo = true;
		guardado = false;
	}

	/**
	 * Método para seleccionar a un colegiado de los resultados de una consulta
	 * para realizar sobre él las acciones determinadas por el modo de selección
	 * 
	 * @param coleg
	 *            Colegiado seleccionado de la tabla de resultados
	 * @param md
	 *            Modo de selección, edición, consulta, alta o baja
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void selectColegiado(Colegiado coleg, int md) {
		colegiado = coleg;
		modo = md;
		dni = colegiado.getDni();
		listaProvincias = provinciaService.getList();
		listaProvinciasDir = provinciaService.getList();
		listaColegios = colegioService.getList();
		listaParticipaciones = partColegiadoService
				.getParticipaciones(colegiado);
		nuevo = false;
		guardado = false;

		if (colegiadoSearch.getTemporada() != null) {
			Temporada t = colegiadoSearch.getTemporada();
			for (PartColegiado p : listaParticipaciones) {
				if (p.getTemporada().equals(t)) {
					participacion = p;
				}
			}
		}

	}

	/**
	 * Método para calcular la edad de un colegiado a partir de su fecha de
	 * nacimiento
	 */
	public void calculaEdad() {
		if (nuevo) {
			if (newColegiado.getFechaNac() != null) {
				Long fecNac = newColegiado.getFechaNac().getTime();
				Date d = new Date();
				Long hoy = d.getTime();

				Long dif = hoy - fecNac;

				long mili = 365 * 24 * 60 * 60;
				dif = dif / mili;
				dif = dif / 1000;

				edad = Long.valueOf(dif).intValue();

			} else {
				edad = 0;
			}
		} else {
			if (colegiado.getFechaNac() != null) {
				Long fecNac = colegiado.getFechaNac().getTime();
				Date d = new Date();
				Long hoy = d.getTime();

				Long dif = hoy - fecNac;

				long mili = 365 * 24 * 60 * 60;
				dif = dif / mili;
				dif = dif / 1000;

				edad = Long.valueOf(dif).intValue();

			} else {
				edad = 0;
			}
		}
	}

	/**
	 * Método para obtener una fotografía subida por un usuario
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void obtenerFotografia(UploadEvent event) throws Exception {

		UploadItem item = event.getUploadItem();

		fotoC = item.getData();
		if (fotoC != null) {
			if (nuevo) {
				newColegiado.setFoto(fotoC);
				FacesMessages.instance().add("Fotografia subida correctamente");
			} else {
				colegiado.setFoto(fotoC);
				FacesMessages.instance().add("Fotografía subida correctamente");
			}
		} else {
			FacesMessages.instance().add("No se ha subida ninguna fotografía");
		}

	}

	public void deletePhoto() {
		if (nuevo) {
			if (newColegiado.getFoto() != null) {
				newColegiado.setFoto(null);
				FacesMessages.instance().add(
						"Fotografía eliminada correctamente");
			}
		} else {
			if (colegiado.getFoto() != null) {
				colegiado.setFoto(null);
				FacesMessages.instance().add(
						"Fotografía eliminada correctamente");
			}
		}
	}

	/**
	 * Método para guardar las modificaciones realizadas a un colegiado
	 */
	@Begin(join = true, flushMode = FlushModeType.MANUAL)
	public void guardar() {

		guardado = false;

		if (comprobarNombre()) {
			if (comprobarDni()) {
				if (comprobarFechaNac()) {
					if (nuevo) {
						boolean gdir = direccionService.save(newColegiado
								.getDireccion());
						if (gdir) {
							guardado = colegiadoService.save(newColegiado);
						} else {
							guardado = false;
							FacesMessages.instance().add(
									"Error al guardar la dirección");
						}
					} else {
						boolean gdir = direccionService.save(colegiado
								.getDireccion());
						if (gdir) {
							guardado = colegiadoService.save(colegiado);
						} else {
							guardado = false;
							FacesMessages.instance().add(
									"Error al guardar la direccion");
						}
					}
					if (guardado) {
						if (nuevo) {
							FacesMessages
									.instance()
									.add(
											"Se ha registrado el nuevo colegiado con éxito.");
						} else {
							FacesMessages
									.instance()
									.add(
											"Se han modificado los datos del colegiado con éxito.");
						}
					} else {
						FacesMessages
								.instance()
								.add(
										"Se ha producido un error y no se ha podido completar el proceso de registro.");
					}
				}
			}
		}
	}

	/**
	 * Método que comprueba el nombre del colegiador ya sea de nuevo registro o
	 * un jugador ya existente
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarNombre() {

		boolean estado = false;

		if (nuevo) {
			if (newColegiado.getNombre() != null
					&& newColegiado.getNombre().length() > 0) {
				estado = true;
			}
		} else {
			if (colegiado.getNombre() != null
					&& colegiado.getNombre().length() > 0) {
				estado = true;
			}
		}

		if (!estado) {
			FacesMessages.instance().add(
					"Debes introducir un nombre para el colegiado.");
		}

		return estado;
	}

	/**
	 * Método que comrpueba el dni del colegiado ya sea de nuevo registro o un
	 * jugador ya existente
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarDni() {

		boolean estado = false;

		if (nuevo) {
			if (newColegiado.getDni() != null
					&& newColegiado.getDni().length() == 9) {
				estado = true;
			} else {
				FacesMessages
						.instance()
						.add(
								"El Dni del colegiado debe estar relleno y tener 9 caracteres.");
				return false;
			}
		} else {
			if (dni != null && dni.length() == 9) {
				if (!dni.equals(colegiado.getDni())) {
					estado = colegiadoService.existeDni(dni);
				} else {
					estado = true;
				}
			} else {
				FacesMessages
						.instance()
						.add(
								"El Dni del jugador debe estar relleno y tener 9 caracteres.");
				return false;
			}
		}

		if (!estado) {
			FacesMessages
					.instance()
					.add(
							"El Dni del colegiado debe estar relleno y tener 9 caracteres.");
		}

		return estado;
	}

	/**
	 * Método que comprueba la fecha de naciemiento del colegiado ya sea de
	 * nuevo registro o un colegiado ya existente
	 * 
	 * @return estado de la comprobación
	 */
	public boolean comprobarFechaNac() {

		boolean estado = false;

		if (nuevo) {
			if (newColegiado.getFechaNac() != null && edad >= 16) {
				estado = true;
			}
		} else {
			if (colegiado.getFechaNac() != null && edad >= 16) {
				estado = true;
			}
		}

		if (!estado) {
			FacesMessages
					.instance()
					.add(
							"Debes introducir una fecha de nacimiento válida (edad superior o igual a 16 años).");
		}

		return estado;
	}

	/**
	 * Método para limpiar los datos introducidos en el formulario de
	 * colegiado/nuevo colegiado
	 */
	public void limpiar() {
		newColegiado = null;
		colegiado = null;
		edad = null;
		fotoC = null;
		listaMunicipios = null;
		listaMunicipiosDir = null;
	}

	/**
	 * Método para inicializar todos los parámetros al volver al menú de
	 * búsqueda de equipos
	 */
	public void volver() {
		colegiado = colegiadoService.merge(colegiado);
		limpiar();
	}

	/**
	 * Método para inicializar todos los parámetros al volver al menú principal
	 */
	@End
	public void menu() {
		limpiar();
		colegiadoSearch.limpiar();
	}

	/*
	 * getters and setters
	 */

	/**
	 * 
	 * @return
	 */
	public int getModo() {
		return modo;
	}

	/**
	 * 
	 * @param modo
	 */
	public void setModo(int modo) {
		this.modo = modo;
	}

	/**
	 * 
	 * @return
	 */
	public boolean isNuevo() {
		return nuevo;
	}

	/**
	 * 
	 * @param nuevo
	 */
	public void setNuevo(boolean nuevo) {
		this.nuevo = nuevo;
	}

	/**
	 * 
	 * @return
	 */
	public Colegiado getColegiado() {
		return colegiado;
	}

	/**
	 * 
	 * @param colegiado
	 */
	public void setColegiado(Colegiado colegiado) {
		this.colegiado = colegiado;
	}

	/**
	 * 
	 * @return
	 */
	public String getDni() {
		return dni;
	}

	/**
	 * 
	 * @param dni
	 */
	public void setDni(String dni) {
		this.dni = dni;
	}

	/**
	 * 
	 * @return
	 */
	public PartColegiado getParticipacion() {
		return participacion;
	}

	/**
	 * 
	 * @param participacion
	 */
	public void setParticipacion(PartColegiado participacion) {
		this.participacion = participacion;
	}

	/**
	 * 
	 * @return newColegiado Colegiado a dar de alta
	 */
	public Colegiado getNewColegiado() {
		return newColegiado;
	}

	/**
	 * 
	 * @param newColegiado
	 *            Colegiado
	 */
	public void setNewColegiado(Colegiado newColegiado) {
		this.newColegiado = newColegiado;
	}

	/**
	 * 
	 * @return
	 */
	public Integer getEdad() {
		if (edad == null) {
			calculaEdad();
		}
		return edad;
	}

	/**
	 * 
	 * @param edad
	 */
	public void setEdad(Integer edad) {
		this.edad = edad;
	}

	/**
	 * 
	 * @return guardado True o false si se guardo correctamente o no
	 */
	public boolean isGuardado() {
		return guardado;
	}

	/**
	 * 
	 * @param guardado
	 */
	public void setGuardado(boolean guardado) {
		this.guardado = guardado;
	}

	/**
	 * 
	 * @param fotoC
	 */
	public void setFotoC(byte[] fotoC) {
		this.fotoC = fotoC;
	}

	/**
	 * 
	 * @return listaProvincias List<ProvinciaDic> Lista de provincias
	 */
	public List<ProvinciaDic> getListaProvincias() {
		return listaProvincias;
	}

	/**
	 * 
	 * @param listaProvincias
	 *            List<ProvinciaDic>
	 */
	public void setListaProvincias(List<ProvinciaDic> listaProvincias) {
		this.listaProvincias = listaProvincias;
	}

	/**
	 * 
	 * @return
	 */
	public List<ProvinciaDic> getListaProvinciasDir() {
		return listaProvinciasDir;
	}

	/**
	 * 
	 * @param listaProvinciasDir
	 */
	public void setListaProvinciasDir(List<ProvinciaDic> listaProvinciasDir) {
		this.listaProvinciasDir = listaProvinciasDir;
	}

	/**
	 * 
	 * @return listaMunicipios List<MunicipioDic> Lista de municipios
	 */
	public List<MunicipioDic> getListaMunicipios() {
		if (nuevo) {
			if (newColegiado.getProvincia() != null) {
				listaMunicipios = municipioService.getList(newColegiado
						.getProvincia());
			}
		} else {
			if (colegiado.getProvincia() != null) {
				listaMunicipios = municipioService.getList(colegiado
						.getProvincia());
			}
		}
		return listaMunicipios;
	}

	/**
	 * 
	 * @param listaMunicipios
	 *            List<MunicipioDic>
	 */
	public void setListaMunicipios(List<MunicipioDic> listaMunicipios) {
		this.listaMunicipios = listaMunicipios;
	}

	/**
	 * 
	 * @return
	 */
	public List<MunicipioDic> getListaMunicipiosDir() {
		if (nuevo) {
			if (newColegiado.getDireccion() != null) {
				if (newColegiado.getDireccion().getProvincia() != null) {
					listaMunicipiosDir = municipioService.getList(newColegiado
							.getDireccion().getProvincia());
				}
			}
		} else {
			if (colegiado.getDireccion() != null) {
				if (colegiado.getDireccion().getProvincia() != null) {
					listaMunicipiosDir = municipioService.getList(colegiado
							.getDireccion().getProvincia());
				}
			}
		}
		return listaMunicipiosDir;
	}

	/**
	 * 
	 * @param listaMunicipiosDir
	 */
	public void setListaMunicipiosDir(List<MunicipioDic> listaMunicipiosDir) {
		this.listaMunicipiosDir = listaMunicipiosDir;
	}

	/**
	 * 
	 * @return
	 */
	public List<ColegioDic> getListaColegios() {
		return listaColegios;
	}

	/**
	 * 
	 * @param listaColegios
	 */
	public void setListaColegios(List<ColegioDic> listaColegios) {
		this.listaColegios = listaColegios;
	}

	/**
	 * 
	 * @return
	 */
	public List<PartColegiado> getListaParticipaciones() {
		return listaParticipaciones;
	}

	/**
	 * @param listaParticipaciones
	 */
	public void setListaParticipaciones(List<PartColegiado> listaParticipaciones) {
		this.listaParticipaciones = listaParticipaciones;
	}

}
